"""
Seaborn 组合图表和注释示例

知识点：
1. 添加回归线
2. 添加参考线
3. 文本注释
4. 组合多种图表类型
5. 高亮特定数据点
"""

import seaborn as sns
import matplotlib.pyplot as plt
import pandas as pd
import numpy as np
from scipy import stats

# 先设置 seaborn 主题
sns.set_theme(style="whitegrid")

# 然后强制设置中文字体（必须在 set_theme 之后）
plt.rcParams['font.sans-serif'] = ['PingFang HK', 'Hiragino Sans GB', 'STHeiti', 'Arial Unicode MS']
plt.rcParams['axes.unicode_minus'] = False
plt.rcParams['font.family'] = 'sans-serif'

# 创建数据
np.random.seed(42)
n = 100
data = pd.DataFrame({
    'X': np.random.randn(n) * 10 + 50,
    'Y': np.random.randn(n) * 15 + 60,
    '类别': np.random.choice(['A', 'B', 'C'], n)
})
data['Y'] = data['Y'] + data['X'] * 0.8 + np.random.randn(n) * 5

fig, axes = plt.subplots(2, 2, figsize=(14, 12))
fig.suptitle('组合图表和注释技术', fontsize=16, fontweight='bold')

# 1. 散点图 + 回归线
sns.scatterplot(data=data, x='X', y='Y', alpha=0.6, ax=axes[0, 0])
sns.regplot(data=data, x='X', y='Y', scatter=False, color='red', ax=axes[0, 0])
axes[0, 0].set_title('1. 散点图 + 回归线')

# 2. 添加参考线
sns.scatterplot(data=data, x='X', y='Y', hue='类别', ax=axes[0, 1])
axes[0, 1].axhline(y=data['Y'].mean(), color='r', linestyle='--', label='Y均值')
axes[0, 1].axvline(x=data['X'].mean(), color='g', linestyle='--', label='X均值')
axes[0, 1].legend()
axes[0, 1].set_title('2. 添加参考线')

# 3. 文本注释
sns.scatterplot(data=data, x='X', y='Y', hue='类别', ax=axes[1, 0])
# 标注最大值点
max_idx = data['Y'].idxmax()
axes[1, 0].annotate('最大值', 
                    xy=(data.loc[max_idx, 'X'], data.loc[max_idx, 'Y']),
                    xytext=(10, 10), textcoords='offset points',
                    arrowprops=dict(arrowstyle='->', color='red'),
                    fontsize=12, color='red')
axes[1, 0].set_title('3. 文本注释')

# 4. 高亮特定区域
sns.scatterplot(data=data, x='X', y='Y', hue='类别', ax=axes[1, 1])
axes[1, 1].axvspan(40, 50, alpha=0.2, color='yellow', label='关注区域')
axes[1, 1].legend()
axes[1, 1].set_title('4. 高亮特定区域')

plt.tight_layout()
plt.savefig('/Users/binming/Desktop/CodeBase/python/Python语法/1-常用库/1-数据分析/Seaborn关系图示例/8-组合注释.png', 
            dpi=300, bbox_inches='tight')
plt.show()
